package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	bookApp "BookStack/internal/application/book"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// BookHandler 书籍API处理器
type BookHandler struct {
	bookService bookApp.ApplicationService
	response    presenter.ResponseFormatter
}

// NewBookHandler 创建书籍API处理器
func NewBookHandler(bookService bookApp.ApplicationService) *BookHandler {
	return &BookHandler{
		bookService: bookService,
		response:    presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册书籍相关路由
func (h *BookHandler) RegisterRoutes(r *gin.RouterGroup) {
	// 公开API
	public := r.Group("/book")
	{
		public.GET("", h.ListBooks)
		// public.GET("/:id", h.GetBookByID)	//待优化
		public.GET("/:slug", h.GetBookBySlug)
		public.GET("/category/:id", h.ListBooksByCategory)
		public.GET("/recommended", h.ListRecommendedBooks)
		public.GET("/search", h.SearchBooks)
	}

	// 需要认证的API
	auth := r.Group("/book")
	auth.Use(middleware.JWTAuth()) // 认证中间件
	{
		// 这里可以添加需要用户认证的API
	}

	// 管理员API
	admin := r.Group("/admin/book")
	admin.Use(middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		admin.POST("", h.CreateBook)
		admin.PUT("/:id", h.UpdateBook)
		admin.DELETE("/:id", h.DeleteBook)
		admin.PUT("/:id/status", h.SetBookStatus)
		admin.PUT("/:id/recommended", h.SetBookRecommended)
	}
}

// ListBooks 获取书籍列表
func (h *BookHandler) ListBooks(c *gin.Context) {
	var params bookApp.BookQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 || params.PageSize > 10 {
		params.PageSize = 10
	}

	// 默认只显示已发布的书籍
	statusPublished := 1 // 已发布状态
	if params.Status == nil {
		params.Status = &statusPublished
	}

	resp, err := h.bookService.ListBooks(c, &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// GetBookByID 根据ID获取书籍详情
func (h *BookHandler) GetBookByID(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(bookApp.ValidationError("id", "无效的书籍ID"))
		return
	}

	book, err := h.bookService.GetBookByID(c, uint(id))
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, book)
}

// GetBookBySlug 根据Slug获取书籍详情
func (h *BookHandler) GetBookBySlug(c *gin.Context) {
	slug := c.Param("slug")
	if slug == "" {
		c.Error(bookApp.ValidationError("slug", "无效的书籍Slug"))
		return
	}

	book, err := h.bookService.GetBookBySlug(c, slug)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, book)
}

// ListBooksByCategory 获取分类下的书籍列表
func (h *BookHandler) ListBooksByCategory(c *gin.Context) {
	categoryIDStr := c.Param("id")
	if categoryIDStr == "" {
		c.Error(bookApp.ValidationError("category_id", "无效的分类ID"))
		return
	}

	var params bookApp.BookQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 || params.PageSize > 100 {
		params.PageSize = 20
	}

	// 默认只显示已发布的书籍
	statusPublished := 1 // 已发布状态
	if params.Status == nil {
		params.Status = &statusPublished
	}

	// 可以在查询时在应用层内部处理分类ID过滤
	// 这里可以使用额外的参数传递给应用层

	resp, err := h.bookService.ListBooks(c, &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// ListRecommendedBooks 获取推荐书籍列表
func (h *BookHandler) ListRecommendedBooks(c *gin.Context) {
	var params bookApp.BookQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 || params.PageSize > 100 {
		params.PageSize = 20
	}

	// 设置为查询推荐书籍
	recommendValue := 1 // 推荐状态
	params.Recommend = &recommendValue

	// 默认只显示已发布的书籍
	statusPublished := 1 // 已发布状态
	if params.Status == nil {
		params.Status = &statusPublished
	}

	resp, err := h.bookService.ListBooks(c, &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// SearchBooks 搜索书籍
func (h *BookHandler) SearchBooks(c *gin.Context) {
	keyword := c.Query("q")
	if keyword == "" {
		c.Error(bookApp.ValidationError("q", "搜索关键词不能为空"))
		return
	}

	page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err != nil || page < 1 {
		page = 1
	}

	pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	if err != nil || pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}

	resp, err := h.bookService.SearchBooks(c, keyword, page, pageSize)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// CreateBook 创建书籍
func (h *BookHandler) CreateBook(c *gin.Context) {
	var req bookApp.CreateBookRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 从认证信息中获取当前用户ID
	userID := getUserIDFromContext(c)
	req.CreatedBy = userID

	book, err := h.bookService.CreateBook(c, &req)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, book)
}

// UpdateBook 更新书籍
func (h *BookHandler) UpdateBook(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(bookApp.ValidationError("id", "无效的书籍ID"))
		return
	}

	var req bookApp.UpdateBookRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 从认证信息中获取当前用户ID
	userID := getUserIDFromContext(c)

	book, err := h.bookService.UpdateBook(c, uint(id), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, book)
}

// DeleteBook 删除书籍
func (h *BookHandler) DeleteBook(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(bookApp.ValidationError("id", "无效的书籍ID"))
		return
	}

	// 从认证信息中获取当前用户ID
	userID := getUserIDFromContext(c)

	if err := h.bookService.DeleteBook(c, uint(id), userID); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// SetBookStatus 设置书籍状态
func (h *BookHandler) SetBookStatus(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(bookApp.ValidationError("id", "无效的书籍ID"))
		return
	}

	var req bookApp.BookStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 从认证信息中获取当前用户ID
	userID := getUserIDFromContext(c)

	// 根据状态值调用不同的方法
	var book *bookApp.BookResponse
	if req.Status == 1 {
		// 如果状态是已发布，调用PublishBook方法
		book, err = h.bookService.PublishBook(c, uint(id), userID)
	} else {
		// 获取当前书籍用于保留现有信息
		currentBook, err := h.bookService.GetBookByID(c, uint(id))
		if err != nil {
			c.Error(err)
			return
		}

		// 创建更新请求，保留现有信息
		updateReq := &bookApp.UpdateBookRequest{
			Title:       currentBook.Title,
			Description: currentBook.Description,
			Cover:       currentBook.Cover,
			Slug:        currentBook.Slug,
		}

		// 使用现有的UpdateBook方法
		book, err = h.bookService.UpdateBook(c, uint(id), updateReq, userID)
	}

	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, book)
}

// SetBookRecommended 设置书籍推荐状态
func (h *BookHandler) SetBookRecommended(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(bookApp.ValidationError("id", "无效的书籍ID"))
		return
	}

	var req bookApp.BookRecommendedRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 从认证信息中获取当前用户ID
	userID := getUserIDFromContext(c)

	// 使用ToggleBookRecommend方法，传递推荐状态和用户ID
	book, err := h.bookService.ToggleBookRecommend(c, uint(id), req.Recommended, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, book)
}
